home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / -archivi / -recent2 / gaplib.lha / GAPLib_Beta / examples / FuncOpt2.c < prev    next >
C/C++ Source or Header  |  1999-01-29  |  4KB  |  197 lines

  1. /*
  2.  *
  3.  * Function Optimization with very high rate of mutation and
  4.  * harsh selection. 
  5.  *
  6.  * Fitness Function : f(x,y) = 21.5 + x*sin(4*PI*x) + y*sin(20*PI*y)
  7.  * For x = ]-3,12.1[ and y = ]4.1,5.8[
  8.  *
  9.  * This program does in no way claim to be optimal, so as an exercise
  10.  * you might consider to try and improve it.
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <limits.h>
  16. #include <math.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <time.h>
  20.  
  21. #include <GAP.h>
  22.  
  23. static long int Polyphant_Size;    /* No. of bits in one Polyphant. */
  24.  
  25. #ifndef    PI
  26. #define    PI    3.141592653589793238462
  27. #endif
  28.  
  29. struct   Polyphant {
  30.     unsigned long    x1,x2;
  31. };
  32.  
  33.  
  34. double fitfunc(struct Polyphant *);
  35. void mutator(struct Polyphant *,int);
  36. void crosser(struct Polyphant *,struct Polyphant *,int);
  37.  
  38. /* Mutation frequencies. Higer = MoreCommon */
  39.  
  40. int   Common;
  41. int   Uncommon;
  42.  
  43. int isvalid(struct Polyphant *);
  44.  
  45. int main(int cnt,char *arg[])
  46. {
  47. struct Population *Pop;
  48. struct Polyphant *Polly;
  49. int n,Generations=10;
  50. FILE  *max,*average,*median;
  51.  
  52. struct   TagItem  EvolveTags[]={ /* Tags for the Evolve() function */
  53.    {EVL_Dump,     0L},
  54.    {EVL_Elite,    0L},
  55.    {EVL_PreMutate,TRUE},
  56.    {EVL_Evaluator,(IPTR)fitfunc},
  57.    {EVL_Mutator,  (IPTR)mutator},
  58.    {EVL_Crosser,  (IPTR)crosser},
  59.    {EVL_Select,   DRANDOM},
  60.    {TAG_DONE,     0L}
  61. };
  62.  
  63. EnterGAP(2);
  64.  
  65. InitRand(time(NULL));
  66.  
  67. Polyphant_Size = sizeof(struct Polyphant) << 3;
  68.  
  69. if(cnt>2)   /* VERY simple argument parsing */
  70.    fprintf(stderr,"%s [Generations]\n",arg[0]);
  71.  
  72. if(cnt==2) {
  73.    Generations=atoi(arg[1]);  
  74.    if(!Generations)
  75.       Generations=10;
  76. }
  77.  
  78. Pop=CreatePopulation(50,sizeof(struct Polyphant),NULL);   /* Create 50 Polyphants, 
  79.                                                                                  use default random init function. */
  80. /* Report files. */
  81.  
  82. max=fopen("Max","wb");
  83. average=fopen("Average","wb");
  84. median=fopen("Median","wb");
  85.  
  86. if(Pop && max && average && median) {
  87.  
  88.    /* Change these to control the rate of mutation. */
  89.     /* Total mutationrate = (10/32 + 10/32)/32 ~= 2% per bit. */
  90.    Common = 10;    /* Rate of common mutations (10/32) */
  91.    Uncommon=10;    /* Rate of uncommon mutations (10/32) */
  92.  
  93.    for(n=0;n!=Generations;n++) {
  94.  
  95.       Pop=Evolve(Pop,EvolveTags);
  96.  
  97.       if(n<((Pop->NumPolys)>>2)) {  /* Change elitism and dumping on the fly. */
  98.          EvolveTags[0].ti_Data=n>>2;   /* Dump */
  99.          EvolveTags[1].ti_Data=n;   /* Elite */
  100.       }
  101.  
  102.       printf("Generation %ld : Average = %f, Max = %f, Med = %f\n",Pop->Generation,Pop->Stat.AverageFitness,Pop->Stat.MaxFitness,Pop->Stat.MedianFitness);
  103.  
  104.       fprintf(max,"%ld.0 %f\n",Pop->Generation,Pop->Stat.MaxFitness);
  105.       fprintf(average,"%ld.0 %f\n",Pop->Generation,Pop->Stat.AverageFitness);
  106.       fprintf(median,"%ld.0 %f\n",Pop->Generation,Pop->Stat.MedianFitness);
  107.  
  108.    } /* n */
  109.  
  110.     Polly = Pop->Stat.Max;
  111.    printf("Finished: Best individual (%f,%f).\n",IRange(Polly->x1,-3.0,12.1),IRange(Polly->x2,4.1,5.8));
  112.  
  113. } else { /* (Pop && max && average && median) */
  114.    fprintf(stderr,"Initialization failed!\n");
  115. }
  116.  
  117. if(Pop) DeletePopulation(Pop); /* Finished */
  118. if(max) fclose(max);
  119. if(average) fclose(average);
  120. if(median) fclose(median);
  121.  
  122. return(0);
  123. }
  124.  
  125. double fitfunc(struct Polyphant *Polly)
  126. {
  127. double x1,x2;
  128. x1 = IRange(Polly->x1,-3.0,12.1);
  129. x2 = IRange(Polly->x2,4.1,5.8);
  130. return( 21.5 + x1*sin(4*PI*x1) + x2*sin(20*PI*x2) );
  131. }
  132.  
  133. void mutator(struct Polyphant *Polly,int Size)
  134. {
  135. int i;
  136.  
  137. if(Rnd(32)<Common) { /* common mutation */
  138.       Flip(Polly,Rnd(Size<<3));
  139. } else if(Rnd(32)<Uncommon) { /* uncommon mutation */
  140.    for(i=0;i!=Size;i++) {
  141.         ((char *)Polly)[i]=Rnd(256);
  142.     }
  143.  
  144. if(Polly->x1 == 0) {
  145.     Polly->x1+=1;
  146. }
  147. if(Polly->x1 == ULONG_MAX) {
  148.     Polly->x1-=1;
  149. }
  150. if(Polly->x2 == 0) {
  151.     Polly->x2+=1;
  152. }
  153. if(Polly->x2 == ULONG_MAX) {
  154.     Polly->x2-=1;
  155. }
  156.  
  157.  
  158. }
  159.  
  160. }
  161.  
  162. void crosser(struct Polyphant *Polly,struct Polyphant *Tweety,int Size)
  163. {
  164. Crossover(&(Polly->x1),&(Tweety->x1),Rnd(sizeof(long)<<3),sizeof(long));
  165. Crossover(&(Polly->x2),&(Tweety->x2),Rnd(sizeof(long)<<3),sizeof(long));
  166. if(Rnd(4)==2) {
  167.     Crossover(Polly,Tweety,Rnd(Size<<3),Size);
  168. }
  169.  
  170. if(Polly->x1 == 0) {
  171.     Polly->x1+=1;
  172. }
  173. if(Polly->x1 == ULONG_MAX) {
  174.     Polly->x1-=1;
  175. }
  176. if(Polly->x2 == 0) {
  177.     Polly->x2+=1;
  178. }
  179. if(Polly->x2 == ULONG_MAX) {
  180.     Polly->x2-=1;
  181. }
  182.  
  183. if(Tweety->x1 == 0) {
  184.     Tweety->x1+=1;
  185. }
  186. if(Tweety->x1 == ULONG_MAX) {
  187.     Tweety->x1-=1;
  188. }
  189. if(Tweety->x2 == 0) {
  190.     Tweety->x2+=1;
  191. }
  192. if(Tweety->x2 == ULONG_MAX) {
  193.     Tweety->x2-=1;
  194. }
  195.  
  196. }
  197.